现在开发项目,提到图表,十有八九都会选择 echarts,不论是使用、性能或者社区活跃度都不错。
使用
react 项目可以使用 echarts-for-react
,^3
版本对应 echarts^5
import ReactECharts from "echarts-for-react";
const option = {};
<ReactECharts
option={option}
notMerge={true}
lazyUpdate={true}
onChartReady={this.onChartReadyCallback}
onEvents={EventsDict}
/>;
绝大部分项目都是只需要绘制小数据量的图表,外加一些动画或者悬浮交互,这些通过调用 api 就能满足需求。当然,api 也确实有很多,建议先熟悉初始配置、setOption
、事件,之后再根据具体图表类型再进一步熟悉和应用
文档链接
- echarts handbook
- echarts-for-react 文档
- echarts 示例。可以通过示例来引导 pm 或者其他需求方确定图表需求,避免出现复杂又不太合理的图表交互需求…
遇到的问题
实际上我遇到的问题,可以归纳为 高频数据下发,数据量不保证,前端页面需要确保曲线图绘制的实时性。这里涉及到三点可能导致卡顿的问题
- 高频数据
- 大对象数据解析
- 绘制曲线图
解决办法主要是以下几点:
1.数据解析角度
-
减小数据量
-
后端(c++)解析数据,相比 js 解析数据肯定要更快
-
web worker。分担主线程解析和生成曲线数据的压力
-
分流。可在后端或者 worker 中处理,按固定频率绘制曲线
2.绘制角度
-
降采样。不适配需求,当然 echarts 有很好的降采样算法,单看趋势的话,其实完全可以试试 ~
-
去除动画,减少绘制耗时
-
设置 showSymbol 为 false,即减少绘制元素,包括不必要的悬浮框等
-
只渲染固定范围,控制耗时
最终的优化方案其实就用到了上面提到的几点:
- 后端处理数据,转换成前端绘制需要的曲线数据,做好节流(比如 1s 绘制一次)
- 前端接收 json 并解析
- 维护一个队列,控制只绘制固定范围(用户自定义)的曲线,将耗时控制在 30ms 以内(不用 worker 是因为这一步处理耗时并不多)
- 前端去除多余的动画、绘制元素以确保不产生无用的耗时
其他优化思路,待验证
- 升级 echarts5,使用脏矩形优化,初步对比优化效果不明显。可能是数据量还没达到百万级别?
Web Worker
+Transferable Objects
- 增量渲染
appendData
- 离屏渲染
- canvas 分层
这些思路可能还要研究源码才能验证,因为经过之前的优化方案已经足以满足需求也就不再继续研究了。有空的话接着学习下 ~
按需引入
默认的引入方式会引入 echarts 中所有的图表和组件,建议按需引入
// 默认引入方式
import * as echarts from "echarts";
按需引入,详情参考 按需引入 ECharts 图表和组件,主要代码如下:
// 引入 echarts 核心模块
import * as echarts from "echarts/core";
import { BarChart } from "echarts/charts";
import { TitleComponent, TooltipComponent } from "echarts/components";
import { LabelLayout } from "echarts/features";
// NOTE: 必须引入渲染器
import { CanvasRenderer } from "echarts/renderers";
// 注册组件
echarts.use([
TitleComponent,
TooltipComponent,
BarChart,
LabelLayout,
CanvasRenderer,
]);
// 接下来的使用就跟之前一样了
const myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
// ...
});
echarts-for-react
按需引入(对于 echarts5)
import ReactEChartsCore from "echarts-for-react/lib/core";
import * as echarts from "echarts/core";
import { LineChart } from "echarts/charts";
import {
GridComponent,
TooltipComponent,
TitleComponent,
DatasetComponent,
} from "echarts/components";
// NOTE: 必须引入渲染器
import {
CanvasRenderer,
// SVGRenderer,
} from "echarts/renderers";
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
LineChart,
CanvasRenderer,
]);
const option = {};
<ReactEChartsCore
echarts={echarts}
option={option}
notMerge={true}
lazyUpdate={true}
onChartReady={this.onChartReadyCallback}
onEvents={EventsDict}
/>;
echarts 5 以下版本的按需引入参考文档(搜 With Echarts.js v3 or v4:) https://github.com/hustcc/echarts-for-react/
图表对比
实际上我用过的图表库很少,所以这里只是简单提一嘴..更详细的 benchmark 还需要自行搜索资料和验证 ~
echarts
。不论是图表类型、api、使用体验和性能都是目前最佳,但是封装程度非常高,所以很难对其进一步抽象和封装,表现为定制化能力差G2
。对比前者,在数据对图形的控制上要更灵活,即定制化能力更强biz-charts
。基于 G2 进一步封装,更易于使用
在这版需求中,其实我基本上复刻了 webviz 的曲线图组件,支持实时和离线场景,后续可以尝试封装成通用组件,并提供下借鉴经验。可以期待下哈 ~